#####################################################################
# File:         ModelSectionList.py
# Product:      KnowledgeEngine
#
# Copyright:    Copyright (c) 2002, Faulkner Technologies.
# Author:       Brian Oliver
#
# Description:  This file defines the ModelSectionList class, a tool
#               to present a list of sections in a model Toolbar
#
# See Also:     Element
#####################################################################

#####################################################################
## Knowledge Engine Library Imports
from Products.KnowledgeEngine.Common import *
from Products.KnowledgeEngine.KnowledgeEngineCore import *
from Products.KnowledgeEngine.Elements.Toolbar.ToolbarTool import ToolbarTool, ToolbarToolInfo
from Products.KnowledgeEngine.PropertyDefinition import PropertyDefinition
from Products.KnowledgeEngine.PropertyFormats import *
from Products.KnowledgeEngine.PropertyTypes import *

#####################################################################
## Zope Library Imports
from Globals import DTMLFile
from ImageFile import ImageFile

#####################################################################
## Python Library Imports
# (none)

#####################################################################
## ModelSectionListInfo Class Definition
class ModelSectionListInfo(ToolbarToolInfo):
    """
        Defines the class info methods, defining information about
        the class without needing an instance of the class
    """
    
    #---------------------------------------------------------------#
    
    def getClassName(self):
        """
            Returns the name of the class for which 
            we are providing information.
        """
        return "ModelSectionList"

    #---------------------------------------------------------------#

    def getDisplayName(self):
        """
            Return a friendly name for the class instances
            (this is used for displaying in lists etc)
        """
    
        return "Page Navigation Dropdown"
        
    #---------------------------------------------------------------#

    def getIdentityType(self):
        """
            Return the identity type.  
        """
        
        return "toolMSL"
        
    #---------------------------------------------------------------#
    
    def getClassIcon(self):
        """
            Return the appropriate icon file for the class.
        """
        
        return ImageFile('icon.png', globals())
        
    #---------------------------------------------------------------#

    def isPermittedInContainer(self, containerClassInfo, containerInstance = None, instance=None):
        """
            ABSTRACT: Returns if class instances (instance) is permitted in 
            the specified container (containerInstance)
            
            NOTE: This is from this class' instance perspective.
        """
        
        #DEFAULT RULE: ModelSectionLists are only permitted in Toolbars
        return containerClassInfo.isInstanceOf('Toolbar') and ((containerInstance == None) or (containerInstance != None and len(containerInstance.getChildrenByInstanceOf(self.getClassName())) == 0))
    
    #---------------------------------------------------------------#

    def onConfigureProperties(self):
        """
            Automatically called by the Knowledge Engine once
            the class has been loaded.  Use this method to register 
            class specific properties using the PropertyReflection interface.
            
            If this class is sub-classed, a call must be made to
            the super-class to ensure super-class properties are
            correctly registered
            
            NOTE: This method is called before ClassInfo.onAfterStartup()            
        """

        #initialise the super-class properties for reflection
        ToolbarToolInfo.onConfigureProperties(self)

        #set the default 'title'
        self.getPropertyDefinition('title').setDefaultValue('Pages')

        #set the default 'id'
        self.getPropertyDefinition('id').setDefaultValue('lstPages')

    #---------------------------------------------------------------#

#####################################################################
## ModelSectionList Class Definition
class ModelSectionList(ToolbarTool):
    """
        A class to represent a list of model sections in a model toolbar
    """

    #---------------------------------------------------------------#

    #ABSTRACT TRANSIENT: a ClassInfo implementation instance to provide info about this class
    _CLASSINFO = ModelSectionListInfo()

    #---------------------------------------------------------------#

    # Custom zope manage_preview to permit previews of components.
    preview_html = DTMLFile('index_html', globals())

    #---------------------------------------------------------------#

    def __init__(self, id, identity):
        "Constructor for the ModelSectionList"        

        ToolbarTool.__init__(self, id, identity)
        
        #perform onAfterInstanciation processing
        self.onAfterInstanciation()

    #---------------------------------------------------------------#

    def onAfterInstanciation(self):
        """
            Handle Knowledge Engine specific actions after this object 
            has been loaded into memory.  
            
            This is useful for performing backwards compatibility
        """        
        
        #perform default processing
        ToolbarTool.onAfterInstanciation(self)
        
    #---------------------------------------------------------------#

    def isPreviewPermitted(self):
        """
            Return if the Element is allowed to be previewed.
            
            By default all elements can't be previewed, some however
            should can be previewed. eg: HTMLHeaderFooters
        """
        
        return true
        
    #---------------------------------------------------------------#

    def getContent(self, contentZone, forGenericObject = None, componentContext = None, assessment = None):
        """
            Return the Element generated 
            content for the specified contentZone (a string).   

            This method is called by the Model.index_html dtml file
            to customise the appearance of the output.
            
            By overriding this method, Elements have the opportunity
            to perform customization of the output from a Model
            during the assessment process.
        """
        
        #the result
        result = ""

        if contentZone == "PAGE_DECLARATIONS":

            #add the renderModelSelectionList method (always)
            result = self._v_javascriptModelSectionList

        elif contentZone == "PAGE_REFRESH":
            
            #get the section we are currently in (the forGenericObject)            
            lPage = forGenericObject

            #is there more than one section? (add calls to renderModelSelectionList)
            if lPage is not None and len(lPage.getModel().getPages(assessment)) > 1:                
                result += 'renderModelSelectionList(document.getElementById("navTop"));'
                result += 'renderModelSelectionList(document.getElementById("navBottom"));'
            
        elif contentZone == "TOOLBAR_TOP" or contentZone == "TOOLBAR_BOTTOM":
        
            #output the button
            if contentZone == "TOOLBAR_TOP":
                prefix = "Top"
            else:
                prefix = "Bottom"
            
            #get the section we are currently in (the forGenericObject)            
            lPage = forGenericObject
                                   
            #output the sections (if we have been supplied a context page)
            if lPage is not None:
                #get the model for the page                
                lModel = lPage.getModel(componentContext)

                #get the pages from the model
                lPages = lModel.getPages(assessment)
                
                #is there more than one page?
                if len(lPages) > 1:                
                    #output the section list
                    result += '<select class="keToolbarDropDown" name="nav%s" onChange="navigateToPage(getPage(getSelectValue(this)));">' % (prefix,)            

                    #output the current section 
                    #(the rest may be hidden and will be rendered dynamically)
                    result += '<option value="%s" selected>%s</option>' % (lPage.getIdentity(componentContext), lPage.getNavigationTitle())                        
            
                    #output the end of the list
                    result += '</select>'
            
                else:
                    #only one section 
                    result += '<span class="keDropDown" name="nav%s">%s</span>' % (prefix, lPage.getTitle())

            else:
                #output preview style
                result += '<select class="keDropDown">'
                result += '<option>Preview</option>'
                result += '</select>'                    
            
        return result
        
    #---------------------------------------------------------------#

    ## The Javascript to dynamically update the model section list
    
    _v_javascriptModelSectionList = """    
    function renderModelSelectionList(cmbPageList) {
        var optionIdx = 0;
        for(var i = 0; i < arrPages.length; i++) {
            var section = arrPages[i];
            if (section.isShown()) {
                if (optionIdx < cmbPageList.options.length && cmbPageList.options.item(optionIdx).value == section.getIdentity()) {
                    optionIdx++;
                } else {
                    var optPage = document.createElement("option");
                    optPage.text = section.getTitle();
                    optPage.value = section.getIdentity();

                    //add to the end?
                    if (optionIdx == cmbPageList.options.length) {
                        cmbPageList.options.add(optPage);
                    } else {
                        cmbPageList.options.add(optPage, optionIdx);
                    } //if
                    optionIdx++;
                } //if
            } else {
                if (optionIdx < cmbPageList.options.length && cmbPageList.options.item(optionIdx).value == section.getIdentity()) {
                    cmbPageList.options.remove(optionIdx);
                } else {
                    //skip:everything is ok for this section
                } //if
            } //if
        } //for    
    } //renderModelSelectionList        
    """
        
    #---------------------------------------------------------------#


#####################################################################
## Class Initialisation

# Register Class Information with the Knowledge Engine
registerGenericObjectClass(ModelSectionList)

#####################################################################
